import java.math.BigInteger;

/**
 * @author by zyl
 * @date 2020/3/28.
 */
public class Agreement {
    private static ECPoint P;
    private static ECPoint PK;
    private static ECCOperator ec;

    static {
        ec=new ECCOperator();
        ECPoint G=new ECPoint(new BigInteger("2"),new BigInteger("4"));
        P=ec.multiply(G,new BigInteger("123456"));
        String sPK= FileUtil.readTag(CommonValue.KeyTable,"KGC").split(" ")[1];
        PK=new ECPoint(new BigInteger(sPK.split(",")[0]),new BigInteger(sPK.split(",")[1]));
    }

    public static void agreement(){
        System.out.println("Start sending ij to A");
        String ij="11";
        SocketUtils.out(CommonValue.C_A_IP,CommonValue.C_A_PORT,ij);
        String request=SocketUtils.in(CommonValue.B_C_Port);
        System.out.println("Getting from B:"+request);
        BigInteger c=new BigInteger(CharacterUtils.getRandomInteger(16));
        System.out.println("Selects a random c:"+c);
        ECPoint Xc=ec.multiply(P,c);
        System.out.println("Computing Xc:"+Xc.toString());
        String RC=CharacterUtils.getRandomInteger(16);
        System.out.println("Computing RC:"+RC);
        String KCij=FileUtil.readTag(CommonValue.KeyTable,"C11").split(" ")[1];
        String IDC=FileUtil.readTag(CommonValue.IDTable,"C11").split(" ")[1];
        String HCB=HashUtils.Hash(RC+KCij+IDC);
        System.out.println("HCB:"+HCB);
        String linkData1=Xc.toString()+":"+IDC+":"+RC;
        String Ec=Base64.encode(XorUtils.xor(linkData1,HCB));
        String toB=Ec+":"+RC;
        SocketUtils.out(CommonValue.C_B_IP,CommonValue.C_B_Port,toB);
        String fromB=SocketUtils.in(CommonValue.B_C_Port);
        System.out.println("Receiving fromB:"+fromB);
        String Ebc=fromB.split(":")[0];
        String RB=fromB.split(":")[1];
        String Ebc_=Base64.decode(Ebc);
        String linkData2=XorUtils.xor(Ebc_,HCB);
        String xuIDA=linkData2.split(":")[0];
        System.out.println("Decoding xuIDA:"+xuIDA);
        String xuIDB=linkData2.split(":")[1];
        System.out.println("Decoding xuIDB:"+xuIDB);
        String xuIDC=linkData2.split(":")[2];
        System.out.println("Decoding xuIDC:"+xuIDC);
        String xXa=linkData2.split(":")[3];
        System.out.println("Decoding xXa:"+xXa);
        String xXc=linkData2.split(":")[4];
        System.out.println("Decoding xXc:"+xXc);
        String xVB=linkData2.split(":")[5];
        System.out.println("Decoding xVB:"+xVB);
        String xxVB=HashUtils.Hash(xuIDA+xuIDB+IDC+RB);
        if(IDC.equals(xuIDC)&&xxVB.equals(xVB)){
            System.out.println("C Verifies B success!");
        }
        else{
            System.out.println("C Verifies B failed!");
        }
        String xax=xXa.split(",")[0];
        String xay=xXa.split(",")[1];
        ECPoint XXA=new ECPoint(new BigInteger(xax),new BigInteger(xay));
        ECPoint cXa=ec.multiply(XXA,c);
        String SSKCA=HashUtils.Hash(xXa.toString()+Xc+cXa.toString());
        System.out.println("SSKCA:"+SSKCA);
        String fromA=SocketUtils.in(CommonValue.A_C_PORT);
        String HAC=fromA.split(":")[0];
        String RA1=fromA.split(":")[1];
        System.out.println("receiving HAC:"+HAC);
        System.out.println("receiving RA1:"+RA1);
        String RC1=CharacterUtils.getRandomInteger(16);
        String HCA=HashUtils.Hash(xuIDA+xuIDB+IDC+SSKCA);
        System.out.println("Computing HCA:"+HCA);
        if(HCA.equals(HAC)){
            System.out.println("C Verifies A success!");
        }
        else{
            System.out.println("C Verifies A failed!");
        }
        String cToA=HCA+":"+RC1;
        SocketUtils.out(CommonValue.C_A_IP,CommonValue.C_A_PORT,cToA);
    }

    public static void main(String args[]){
        agreement();
    }
}